const express = require('express');
const multer = require('multer');
const sharp = require('sharp');
const path = require('path');
const fs = require('fs');
const { ObjectId } = require('mongodb');
const config = require('./config');
const utils = require('./utils');
const axios = require('axios');

// const { getImageCollection } = require('./database');
const { getImageCollection, getTagCollection } = require('./database');


const router = express.Router();

const storage = multer.diskStorage({
    destination: (req, file, cb) => {
        cb(null, config.imagePath);
    },
});

const upload = multer({ storage });

// 中间件，用于获取 imageCollection
router.use(async (req, res, next) => {
    req.imageCollection = await getImageCollection();
    req.tagCollection = await getTagCollection();
    next();
});


router.post('/upload', upload.single('file'), async (req, res) => {
    // 上传图片的逻辑
    try {
        
        // const { name, type } = req.body;
        const file = req.file;
        // console.log({ name, type }, "file.filePath", file)

        const fname = utils.generateHash(file.path) + ".jpg";
        const fpath = path.join(config.imagePath, fname)
        fs.renameSync(file.path, fpath);

        const thumbnailName = fname.replace(/\.(jpg|jpeg|png)$/, ".min.$1");

        // 生成缩略图
        const thumbnailPath = path.join(config.imagePath, thumbnailName);

        const metadata = await sharp(fpath).metadata();
        // console.log("metadata", metadata)
        await sharp(fpath)
            .resize(300, 300, {
                fit: 'inside',
                withoutEnlargement: true,
            })
            .toFile(thumbnailPath);

        // 保存图片信息到数据库
        const imageInfo = {
            name: fname,
            width: metadata.width,
            height: metadata.height,
            size: Math.round(file.size / 1024), // Unit is KB
            tags: [],
            thumbnail: thumbnailName,
            time: Date.now()
        };
        await req.imageCollection.insertOne(imageInfo);

        res.status(200).json({ message: 'Image uploaded successfully' });
    } catch (err) {
        console.error(err);
        res.status(500).json({ message: 'Error uploading image' });
    }
});

router.get('/download', async (req, res) => {
    try {
        const url = decodeURIComponent(req.query.url);
        
        // 下载图片
        const response = await axios({
            url,
            method: 'GET',
            responseType: 'arraybuffer'
        });

        const buffer = Buffer.from(response.data, 'binary');
        
        // 生成文件名和路径
        const fname = Date.now() + ".jpg";
        const fpath = path.join(config.imagePath, fname);


        // 保存图片
        fs.writeFileSync(fpath, buffer);

        const thumbnailName = fname.replace(/\.(jpg|jpeg|png)$/, ".min.$1");
        const thumbnailPath = path.join(config.imagePath, thumbnailName);

        // 获取图片元数据并生成缩略图
        const metadata = await sharp(buffer).metadata();
        await sharp(buffer)
            .resize(300, 300, {
                fit: 'inside',
                withoutEnlargement: true,
            })
            .toFile(thumbnailPath);

        // 保存图片信息到数据库
        const imageInfo = {
            name: fname,
            width: metadata.width,
            height: metadata.height,
            size: Math.round(buffer.length / 1024), // Unit is KB
            tags: [],
            thumbnail: thumbnailName,
            time: Date.now(),
        };
        await req.imageCollection.insertOne(imageInfo);

        res.status(200).json({ message: 'Image downloaded and processed successfully' });
    } catch (err) {
        console.error(err);
        res.status(500).json({ message: 'Error downloading and processing image' });
    }
});

router.get('/images', async (req, res) => {
    // 获取图片列表的逻辑
    try {
        let { page = 1, limit = 10 } = req.query;
        page = Number(page)
        limit = Number(limit)
        const skip = (page - 1) * limit;

        const total = await req.imageCollection.countDocuments({});
        const images = await req.imageCollection
            .find({})
            .skip(skip)
            .limit(limit)
            .toArray();

        res.json({
            data: images,
            total,
            page: parseInt(page),
            limit: parseInt(limit),
        });
    } catch (err) {
        console.error(err);
        res.status(500).json({ message: 'Error retrieving images' });
    }
});

router.delete('/images/:id', async (req, res) => {
    // 删除图片的逻辑
    try {
        const { id } = req.params;

        // 在删除数据库记录之前先获取文件名
        const imageDoc = await req.imageCollection.findOne({ _id: new ObjectId(id) });
        if (!imageDoc) {
            return res.status(404).json({ message: 'Image not found' });
        }
        // console.log("doc------", imageDoc)
        // const imageFilename = imageDoc.filename;
        // const thumbnailFilename = `thumbnail_${imageFilename}`;

        // 执行删除操作
        const result = await req.imageCollection.deleteOne({ _id: new ObjectId(id) });
        if (result.deletedCount === 1) {
            // 删除文件系统上的图片和缩略图
            fs.unlinkSync(path.join(config.imagePath, imageDoc.name));
            fs.unlinkSync(path.join(config.imagePath, imageDoc.thumbnail));

            res.json({ message: 'Image and thumbnail deleted successfully' });
        } else {
            res.status(404).json({ message: 'Image not found' });
        }
    } catch (err) {
        console.error(err);
        res.status(500).json({ message: 'Error deleting image and thumbnail' });
    }
});

router.get('/tags', async (req, res) => {
    try {
        // const tags = await req.tagCollection.distinct('name');
        const tags = await req.tagCollection.find({}).project({ _id: 1, name: 1 }).toArray();
        // res.json(tags);
        res.json(tags);
    } catch (err) {
        console.error(err);
        res.status(500).json({ message: 'Error retrieving tags' });
    }
});

router.post('/images/:id/tags', async (req, res) => {
    try {
        const { id } = req.params;
        const { tagId } = req.body;

        if (!tagId) {
            return res.status(400).json({ message: 'Tag ID is required' });
        }

        const existingTag = await req.tagCollection.findOne({ _id: new ObjectId(tagId) });
        if (!existingTag) {
            return res.status(400).json({ message: 'Tag does not exist' });
        }

        const result = await req.imageCollection.updateOne(
            { _id: new ObjectId(id) },
            { $addToSet: { tags: existingTag } }
        );

        if (result.matchedCount === 0) {
            return res.status(404).json({ message: 'Image not found' });
        }

        res.json({ message: 'Tag added successfully' });
    } catch (err) {
        console.error(err);
        res.status(500).json({ message: 'Error adding tag' });
    }
});


router.delete('/images/:id/tags', async (req, res) => {
    try {
        const { id } = req.params;
        const { tagId } = req.body;

        if (!tagId) {
            return res.status(400).json({ message: 'TagId is required' });
        }

        const result = await req.imageCollection.updateOne(
            { _id: new ObjectId(id) },
            { $pull: { tags: { _id: new ObjectId(tagId) } } }
        );

        if (result.matchedCount === 0) {
            return res.status(404).json({ message: 'Image not found' });
        }

        res.json({ message: 'Tag removed successfully' });
    } catch (err) {
        console.error(err);
        res.status(500).json({ message: 'Error removing tag' });
    }
});

module.exports = router;